import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, ManyToOne, JoinColumn, Index } from 'typeorm';
import { RequestPhase, MappingType, DataType } from './copilot-types';
import { CopilotRequestLog } from './copilot-request-log.entity';

@Entity('copilot_field_mappings')
@Index(['requestLogId'])
@Index(['fromPhase', 'toPhase'])
@Index(['fieldPath'])
@Index(['mappingType'])
export class CopilotFieldMapping {
  @PrimaryGeneratedColumn()
  id: number;

  @Column({ name: 'request_log_id', type: 'int' })
  requestLogId: number;

  @Column({ 
    name: 'from_phase', 
    type: 'enum', 
    enum: RequestPhase,
    comment: '字段变化的源阶段' 
  })
  fromPhase: RequestPhase;

  @Column({ 
    name: 'to_phase', 
    type: 'enum', 
    enum: RequestPhase,
    comment: '字段变化的目标阶段' 
  })
  toPhase: RequestPhase;

  @Column({ 
    name: 'mapping_type', 
    type: 'enum', 
    enum: MappingType,
    comment: '映射变化类型' 
  })
  mappingType: MappingType;

  // === 字段路径信息 ===
  @Column({ name: 'field_path', length: 500, comment: '字段的JSON路径，如: messages[0].content' })
  fieldPath: string;

  @Column({ name: 'from_field_name', length: 200, nullable: true, comment: '源字段名称' })
  fromFieldName: string;

  @Column({ name: 'to_field_name', length: 200, nullable: true, comment: '目标字段名称' })
  toFieldName: string;

  // === 数据类型信息 ===
  @Column({ 
    name: 'from_data_type', 
    type: 'enum', 
    enum: DataType, 
    nullable: true,
    comment: '源数据类型' 
  })
  fromDataType: DataType;

  @Column({ 
    name: 'to_data_type', 
    type: 'enum', 
    enum: DataType, 
    nullable: true,
    comment: '目标数据类型' 
  })
  toDataType: DataType;

  // === 值信息（支持复杂对象存储） ===
  @Column({ name: 'from_value', type: 'json', nullable: true, comment: '源字段值' })
  fromValue: any;

  @Column({ name: 'to_value', type: 'json', nullable: true, comment: '目标字段值' })
  toValue: any;

  @Column({ name: 'from_value_preview', type: 'text', nullable: true, comment: '源值的字符串预览（用于显示）' })
  fromValuePreview: string;

  @Column({ name: 'to_value_preview', type: 'text', nullable: true, comment: '目标值的字符串预览（用于显示）' })
  toValuePreview: string;

  // === 转换规则信息 ===
  @Column({ name: 'transformation_rule', length: 500, nullable: true, comment: '转换规则描述' })
  transformationRule: string;

  @Column({ name: 'transformer_name', length: 100, nullable: true, comment: '执行转换的适配器名称' })
  transformerName: string;

  // === 元数据 ===
  @Column({ name: 'is_sensitive', type: 'boolean', default: false, comment: '是否包含敏感数据' })
  isSensitive: boolean;

  @Column({ name: 'is_redacted', type: 'boolean', default: false, comment: '是否已脱敏' })
  isRedacted: boolean;

  @Column({ name: 'confidence_score', type: 'decimal', precision: 3, scale: 2, nullable: true, comment: '映射置信度(0-1)' })
  confidenceScore: number;

  @Column({ name: 'validation_status', length: 20, default: 'unknown', comment: '验证状态: valid/invalid/unknown' })
  validationStatus: string;

  // === 调试信息 ===
  @Column({ name: 'debug_info', type: 'json', nullable: true, comment: '调试信息' })
  debugInfo: Record<string, any>;

  @Column({ name: 'notes', type: 'text', nullable: true, comment: '备注信息' })
  notes: string;

  @CreateDateColumn({ name: 'created_at' })
  createdAt: Date;

  // === 关联关系 ===
  @ManyToOne(() => CopilotRequestLog, requestLog => requestLog.fieldMappings, { onDelete: 'CASCADE' })
  @JoinColumn({ name: 'request_log_id' })
  requestLog: CopilotRequestLog;

  // === 便捷方法 ===

  /**
   * 生成字段变化的人类可读描述
   */
  getChangeDescription(): string {
    switch (this.mappingType) {
      case MappingType.FIELD_ADDED:
        return `新增字段 "${this.toFieldName}" (${this.toDataType})`;
      
      case MappingType.FIELD_REMOVED:
        return `移除字段 "${this.fromFieldName}"`;
      
      case MappingType.FIELD_MODIFIED:
        return `修改字段 "${this.fromFieldName}" 的值`;
      
      case MappingType.FIELD_RENAMED:
        return `重命名字段 "${this.fromFieldName}" → "${this.toFieldName}"`;
      
      case MappingType.TYPE_CHANGED:
        return `字段 "${this.fromFieldName}" 类型变更: ${this.fromDataType} → ${this.toDataType}`;
      
      case MappingType.VALUE_TRANSFORMED:
        return `转换字段 "${this.fromFieldName}" 的值`;
      
      case MappingType.STRUCTURE_CHANGED:
        return `字段 "${this.fromFieldName}" 结构变更`;
      
      default:
        return `字段变化: ${this.fromFieldName} → ${this.toFieldName}`;
    }
  }

  /**
   * 获取变化的严重程度
   */
  getChangeSeverity(): 'low' | 'medium' | 'high' {
    switch (this.mappingType) {
      case MappingType.FIELD_MODIFIED:
      case MappingType.VALUE_TRANSFORMED:
        return 'low';
      
      case MappingType.FIELD_RENAMED:
      case MappingType.TYPE_CHANGED:
        return 'medium';
      
      case MappingType.FIELD_ADDED:
      case MappingType.FIELD_REMOVED:
      case MappingType.STRUCTURE_CHANGED:
        return 'high';
      
      default:
        return 'medium';
    }
  }

  /**
   * 检查是否为关键字段变化
   */
  isCriticalChange(): boolean {
    const criticalPaths = [
      'model',
      'messages',
      'max_tokens',
      'temperature',
      'stream'
    ];

    return criticalPaths.some(path => 
      this.fieldPath.toLowerCase().includes(path.toLowerCase())
    );
  }

  /**
   * 生成用于显示的值预览
   */
  static generateValuePreview(value: any, maxLength: number = 200): string {
    if (value === null) return 'null';
    if (value === undefined) return 'undefined';
    
    const str = typeof value === 'string' ? value : JSON.stringify(value);
    
    if (str.length <= maxLength) {
      return str;
    }
    
    return str.substring(0, maxLength - 3) + '...';
  }

  /**
   * 检测数据类型
   */
  static detectDataType(value: any): DataType {
    if (value === null) return DataType.NULL;
    if (value === undefined) return DataType.UNDEFINED;
    if (typeof value === 'string') return DataType.STRING;
    if (typeof value === 'number') return DataType.NUMBER;
    if (typeof value === 'boolean') return DataType.BOOLEAN;
    if (Array.isArray(value)) return DataType.ARRAY;
    if (typeof value === 'object') return DataType.OBJECT;
    
    return DataType.STRING; // fallback
  }

  /**
   * 创建字段映射记录的工厂方法
   */
  static create(params: {
    requestLogId: number;
    fromPhase: RequestPhase;
    toPhase: RequestPhase;
    mappingType: MappingType;
    fieldPath: string;
    fromFieldName?: string;
    toFieldName?: string;
    fromValue?: any;
    toValue?: any;
    transformationRule?: string;
    transformerName?: string;
  }): CopilotFieldMapping {
    const mapping = new CopilotFieldMapping();
    
    mapping.requestLogId = params.requestLogId;
    mapping.fromPhase = params.fromPhase;
    mapping.toPhase = params.toPhase;
    mapping.mappingType = params.mappingType;
    mapping.fieldPath = params.fieldPath;
    mapping.fromFieldName = params.fromFieldName || null;
    mapping.toFieldName = params.toFieldName || null;
    mapping.fromValue = params.fromValue;
    mapping.toValue = params.toValue;
    mapping.transformationRule = params.transformationRule || null;
    mapping.transformerName = params.transformerName || null;

    // 自动检测数据类型
    if (params.fromValue !== undefined) {
      mapping.fromDataType = CopilotFieldMapping.detectDataType(params.fromValue);
      mapping.fromValuePreview = CopilotFieldMapping.generateValuePreview(params.fromValue);
    }

    if (params.toValue !== undefined) {
      mapping.toDataType = CopilotFieldMapping.detectDataType(params.toValue);
      mapping.toValuePreview = CopilotFieldMapping.generateValuePreview(params.toValue);
    }

    return mapping;
  }
}